﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;

namespace Billing
{
    public class _Reflection
    {
        public static Hashtable Reflect(string path, string[] Interfeices)
        {
            Hashtable ht = new Hashtable();
            Assembly asmb;
            asmb = Assembly.GetEntryAssembly();//.LoadFile(path);
            //Search Types in Extended module.
            foreach (System.Reflection.AssemblyName rs in asmb.GetReferencedAssemblies())
            { ExamineAssembly(Assembly.Load(rs.FullName), Interfeices, ht); }
            //serch type in main module
            ExamineAssembly(asmb, Interfeices, ht);
            return ht;
        }

        public static void ExamineAssembly(Assembly asmb, string[] Interfeices, Hashtable Plugins)
        {
            foreach (Type T in asmb.GetTypes())
            {
                if (T.IsPublic)
                {
                    if (((T.Attributes & TypeAttributes.Abstract) != TypeAttributes.Abstract))
                    {
                        foreach (string interf in Interfeices)
                        {
                            object obj = T.GetInterface(interf, true);
                            if (obj != null)
                            {
                                if (Plugins.Contains(T.FullName))
                                    Plugins[T.FullName] = T;
                                else
                                    Plugins.Add(T.FullName, T);
                            }
                        }
                    }
                }


            }
        }

        public static Hashtable FindPlugins(string strPath, string[] Interfeices, Hashtable Plugins)
        {
            if (Plugins == null)
                Plugins = new Hashtable();

            string[] strDLLs;
            int intIndex;

            Assembly objDLL;
            //Go through all DLLs in the directory, attempting to load them
            strDLLs = System.IO.Directory.GetFileSystemEntries(strPath, "*.dll");

            for (intIndex = 0; intIndex < strDLLs.Length; intIndex++)
            {
                try
                {
                    objDLL = Assembly.LoadFrom(strDLLs[intIndex]);
                    ExamineAssembly(objDLL, Interfeices, Plugins);
                }
                catch (Exception)
                {
                    //Error loading DLL, we don't need to do anything special
                }
            }
            return Plugins;
            //Return all plugins found
        }
    }
}
